﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Navigation;

using System.Globalization;
using System.ServiceModel;
using System.ServiceModel.Security;
using System.ServiceModel.Description;
using CRM.Tools.MetadataBrowser.CrmSdk;

namespace CRM.Tools.MetadataBrowser.Views
{
    public partial class EntityView : Page
    {
        public EntityView()
        {
            InitializeComponent();
        }

        // Executes when the user navigates to this page.
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            string serverUrl = ClientScript.GetServerUrl();

            string entityLogicalName = this.NavigationContext.QueryString["LogicalName"];
            if (String.IsNullOrEmpty(entityLogicalName))
                throw new Exception("Entity Logical Name not specifed");


            
            ExecuteRetrieveEntityAttributes(entityLogicalName, new Uri(serverUrl));
            ExecuteRetrieveEntityRelationships(entityLogicalName, new Uri( serverUrl));
        }



        private void ExecuteRetrieveEntityAttributes(string EntityLogicalName, Uri ServerUrl)
        {
            try
            {
                OrganizationServiceClient client = (OrganizationServiceClient)WCFHelper.GetConnection(ServerUrl);
            
                OrganizationRequest request = new OrganizationRequest();
                request.RequestName = "RetrieveEntity";
                request.Parameters = new ParameterCollection();
                request.Parameters.Add(new CRM.Tools.MetadataBrowser.DataModel.KeyValuePair<string, object>("LogicalName", EntityLogicalName));
                request.Parameters.Add(new CRM.Tools.MetadataBrowser.DataModel.KeyValuePair<string, object>("EntityFilters", EntityFilters.Attributes));
                request.Parameters.Add(new CRM.Tools.MetadataBrowser.DataModel.KeyValuePair<string, object>("MetadataId", new Guid("00000000-0000-0000-0000-000000000000")));
                request.Parameters.Add(new CRM.Tools.MetadataBrowser.DataModel.KeyValuePair<string, object>("RetrieveAsIfPublished", false));
                client.ExecuteCompleted += new EventHandler<CrmSdk.ExecuteCompletedEventArgs>(ExecuteRetrieveEntityAttributes_ExecuteCompleted);

                client.ExecuteAsync(request);
             }
            catch (FaultException<OrganizationServiceFault> ex)
            {
                throw ex;
            }
         
        }

        private void ExecuteRetrieveEntityAttributes_ExecuteCompleted(object sender, CrmSdk.ExecuteCompletedEventArgs response)
        {
            try
            {
                EntityMetadata data = (EntityMetadata)response.Result.Results[0].Value;

                var attributes = from a in data.Attributes
                                 orderby a.SchemaName
                                 select a;
          
                uxData.ItemsSource = attributes;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }



        private void ExecuteRetrieveEntityRelationships(string EntityLogicalName, Uri ServerUrl)
        {
            try
            {
                OrganizationServiceClient client = (OrganizationServiceClient)WCFHelper.GetConnection(ServerUrl);

                OrganizationRequest request = new OrganizationRequest();
                request.RequestName = "RetrieveEntity";
                request.Parameters = new ParameterCollection();
                request.Parameters.Add(new CRM.Tools.MetadataBrowser.DataModel.KeyValuePair<string, object>("LogicalName", EntityLogicalName));
                request.Parameters.Add(new CRM.Tools.MetadataBrowser.DataModel.KeyValuePair<string, object>("EntityFilters", EntityFilters.Relationships));
                request.Parameters.Add(new CRM.Tools.MetadataBrowser.DataModel.KeyValuePair<string, object>("MetadataId", new Guid("00000000-0000-0000-0000-000000000000")));
                request.Parameters.Add(new CRM.Tools.MetadataBrowser.DataModel.KeyValuePair<string, object>("RetrieveAsIfPublished", false));
                client.ExecuteCompleted += new EventHandler<CrmSdk.ExecuteCompletedEventArgs>(ExecuteRetrieveEntityRelationships_ExecuteCompleted);

                client.ExecuteAsync(request);
            }
            catch (FaultException<OrganizationServiceFault> ex)
            {
                throw ex;
            }

        }

        private void ExecuteRetrieveEntityRelationships_ExecuteCompleted(object sender, CrmSdk.ExecuteCompletedEventArgs response)
        {
            try
            {
                EntityMetadata data = (EntityMetadata)response.Result.Results[0].Value;
                
                var manyToOne = from mo in data.ManyToOneRelationships
                                orderby mo.SchemaName
                                select mo;

                var manyToMany = from mm in data.ManyToManyRelationships
                                 orderby mm.SchemaName
                                 select mm;

                var oneToMany = from om in data.OneToManyRelationships
                                orderby om.SchemaName
                                select om;
                
                uxManyToOne.ItemsSource = manyToOne;
                uxManyToMany.ItemsSource = manyToMany;
                uxOneToMany.ItemsSource = oneToMany;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        private void Export_Click(object sender, RoutedEventArgs e)
        {
            switch (uxTab.SelectedIndex)
            {
                case 0:
                    ExportGridToExcel(uxData);
                    break;
                case 1:
                    ExportGridToExcel(uxManyToOne);
                    break;
                case 2:
                    ExportGridToExcel(uxManyToMany);
                    break;
                case 3:
                    ExportGridToExcel(uxOneToMany);
                    break;


            }
        }

        private void ExportGridToExcel(DataGrid Grid)
        {
            if (Grid.ItemsSource != null)
            {
                Grid.Export();
            }
            else
            {
                ChildWindow msg = new MessageWindow("No data to export");
                msg.Show();
            }
        }

    }
}
